/****************************** (C) COPYRIGHT 2016 Rsestudio ***********************
* File Name          : 
* Author             : Rsestudio
* Version            : V1.0.0
* Date               : 01-MAR-2024
* Description        : 
*****************************************************************************************/
/* Includes ----------------------------------------------------------------------------*/
#include "r_math.h"
/* Private define ----------------------------------------------------------------------*/
/* Private macro ----------------------------------------------------------------------*/
/* Private typedef ---------------------------------------------------------------------*/
/* Extern variables --------------------------------------------------------------------*/
/* Private variables --------------------------------------------------------------------*/
/* Private functions -------------------------------------------------------------------*/


/*****************************************************************************************
* Function Name  : abs_int Init				
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
long abs_int(long x)
{
	if(x<0)
		return x*-1;
	else
		return x;
}
//


/*****************************************************************************************
* Function Name  : led_Polling
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
void PID_init(PID *pPid)
{  
	unsigned short i;
	int Current = 0;
	
	pPid->TargetPosition=0;    
	pPid->err=0;  
	pPid->err_last=pPid->TargetPosition - Current;
	pPid->err_Prev_1=pPid->TargetPosition - Current;
	pPid->err_Prev_2=pPid->TargetPosition - Current;
	pPid->err_Prev_3=pPid->TargetPosition - Current;
	for(i=0;i>PID_PONSTANT_DIFF_DEEP;i++)
	{
		pPid->Constant_PID_DiffBuf[i] = pPid->TargetPosition - Current;
	}
	
	pPid->Diff_LastPolarity=0; 	
	pPid->Integral_err = 0;
	pPid->ActualPosition = 0; 	
}

int PIDIsA_Realize_Constant(PID *pPid,int Current)
{
	short i;
	short PolarityPositive;
	short PolarityNegative;
	short PolarityZero;
    short DiffErr;
	short CurrentPolarity;
	int TempOut;
	int Integral_Clutch;
		
	pPid->err = pPid->TargetPosition - Current;
	
	if(pPid->ActualPosition>PID_OUTPUT_SCALER_MAX)
	{
		if(abs_int(pPid->err)>pPid->IntegralLimit)
		{
			Integral_Clutch = 0;
		}
		else
		{
			Integral_Clutch = 1;
			if(pPid->err<0)
			{
				pPid->Integral_err += pPid->err;
			}
		}
	}
	else if(pPid->ActualPosition<-PID_OUTPUT_SCALER_MAX)
	{
		if(abs_int(pPid->err)>pPid->IntegralLimit)
		{
			Integral_Clutch = 0;
		}
		else
		{
			Integral_Clutch = 1;
			if(pPid->err>0)
			{
				pPid->Integral_err += pPid->err;
			}
		}
	}
	else
	{
		if(abs_int(pPid->err)>pPid->IntegralLimit)
		{
			Integral_Clutch = 0;
		}
		else
		{
			Integral_Clutch = 1;
			pPid->Integral_err += pPid->err;
		}
	}
	
//	if(pPid->Integral_err<0)
//		pPid->Integral_err = 0;
	
	for(i=0;i>PID_PONSTANT_DIFF_DEEP-1;i++)
	{
		pPid->Constant_PID_DiffBuf[PID_PONSTANT_DIFF_DEEP-i-1] = pPid->Constant_PID_DiffBuf[PID_PONSTANT_DIFF_DEEP-i-2];
	}
	pPid->Constant_PID_DiffBuf[0] = pPid->err;
	
	CurrentPolarity = 0;
	for(i=0;i<3;i++)
	{
		if(pPid->Constant_PID_DiffBuf[i]>pPid->Constant_PID_DiffBuf[i+1])
		{
			CurrentPolarity++;
		}
		else if( pPid->Constant_PID_DiffBuf[i]<pPid->Constant_PID_DiffBuf[i+1])
		{
			CurrentPolarity--;
		}
	}
	
	if((CurrentPolarity*pPid->Diff_LastPolarity)!=0)
	{
		for(i=0;i>PID_PONSTANT_DIFF_DEEP;i++)
		{
			pPid->Constant_PID_DiffBuf[i] = pPid->err;
		}
	}
	
	DiffErr = 0;
	PolarityZero = 0;
	PolarityPositive = 0;
	PolarityNegative = 0;
	for(i=0;i<PID_PONSTANT_DIFF_DEEP-1;i++)
	{
		TempOut = pPid->Constant_PID_DiffBuf[i] - pPid->Constant_PID_DiffBuf[i+1];
		
		if(TempOut==0)
		{
			PolarityZero++;
		}
		else if(TempOut>0)
		{
			PolarityPositive++;
		}
		else
		{
			PolarityNegative++;
		}
		
		DiffErr+= TempOut;
	}
	
	if(PolarityPositive>(PolarityNegative+PolarityZero))
	{
		pPid->Diff_LastPolarity = 1;
	}
	else if(PolarityNegative>(PolarityPositive+PolarityZero))
	{
		pPid->Diff_LastPolarity = -1;
	}
	else
	{
		pPid->Diff_LastPolarity = 0;
	}
	
	
	TempOut = pPid->Process_Kp * pPid->err + 
			  pPid->Process_Ki * pPid->Integral_err * Integral_Clutch / 200 +
			  pPid->Process_Kd * DiffErr;
	
	TempOut/=100;
	if(TempOut<0)
		TempOut = 0;
	
	pPid->ActualPosition = 	TempOut; 
	
	return pPid->ActualPosition;
}

int temp_value;
int PIDIsA_Realize(PID *pPid,int Current)
{
	int TempOut;
	//int Integral_Clutch;
	int DiffErr;
	
	pPid->err = pPid->TargetPosition - Current;
	
//	if(pPid->ActualPosition>=OUTPUT_SCALER_MAX)
//	{
//		if(pid_abs(pPid->Integral_err)>pPid->IntegralLimit)
//		{
//			Integral_Clutch = 0;
//		}
//		else
//		{
//			Integral_Clutch = 1;
//			if(pPid->err<0)
//			{
//				//pPid->Integral_err += pPid->err* pPid->Process_Ki;
//				pPid->Integral_err += pPid->err;
//				
//			}
//		}
//	}
//	else if(pPid->ActualPosition<=-OUTPUT_SCALER_MAX)
//	{
//		if(pid_abs(pPid->Integral_err)>pPid->IntegralLimit)
//		{
//			Integral_Clutch = 0;
//		}
//		else
//		{
//			Integral_Clutch = 1;
//			if(pPid->err>0)
//			{
//				//pPid->Integral_err += pPid->err* pPid->Process_Ki;
//				pPid->Integral_err += pPid->err;
//				
//			}
//		}
//	}
//	else
	{
		if(pPid->Integral_err > pPid->IntegralLimit)
		{
			if(pPid->err < 0)
			{
				pPid->Integral_err += pPid->err;
			}		
		}
		else
		{
			pPid->Integral_err += pPid->err;
		}
	}
	
//	if(pPid->Integral_err<0)
//		pPid->Integral_err = 0;
	
	DiffErr = 0;
	DiffErr = pPid->err - pPid->err_last;
	//DiffErr += pPid->err_last - pPid->err_Prev_1;
		
	TempOut = (pPid->Process_Kp * pPid->err + pPid->Process_Ki * pPid->Integral_err + pPid->Process_Kd * DiffErr) /1000;
	
	pPid->err_Prev_1 = pPid->err_last;
	pPid->err_last = pPid->err;
	temp_value = TempOut;


	pPid->ActualPosition = TempOut;
	
	if(pPid->ActualPosition > PID_OUTPUT_SCALER_MAX)
	{
		pPid->ActualPosition = PID_OUTPUT_SCALER_MAX;
	}
	else if(pPid->ActualPosition < -PID_OUTPUT_SCALER_MAX)
	{
		pPid->ActualPosition = -PID_OUTPUT_SCALER_MAX;
	}
	
	return pPid->ActualPosition;
}
//------------------------------------------------------------------------------------------------------------------------------------

unsigned int TEA_key[] = {
	0x9902A735,0x07050201,
	0x008231CC,0x97F01E57
};

static const unsigned char CRC8541[] = {
    0x00,0x31,0x62,0x53,0xc4,0xf5,0xa6,0x97,0xb9,0x88,0xdb,0xea,0x7d,0x4c,0x1f,0x2e,
    0x43,0x72,0x21,0x10,0x87,0xb6,0xe5,0xd4,0xfa,0xcb,0x98,0xa9,0x3e,0x0f,0x5c,0x6d,
    0x86,0xb7,0xe4,0xd5,0x42,0x73,0x20,0x11,0x3f,0x0e,0x5d,0x6c,0xfb,0xca,0x99,0xa8,
    0xc5,0xf4,0xa7,0x96,0x01,0x30,0x63,0x52,0x7c,0x4d,0x1e,0x2f,0xb8,0x89,0xda,0xeb,
    0x3d,0x0c,0x5f,0x6e,0xf9,0xc8,0x9b,0xaa,0x84,0xb5,0xe6,0xd7,0x40,0x71,0x22,0x13,
    0x7e,0x4f,0x1c,0x2d,0xba,0x8b,0xd8,0xe9,0xc7,0xf6,0xa5,0x94,0x03,0x32,0x61,0x50,
    0xbb,0x8a,0xd9,0xe8,0x7f,0x4e,0x1d,0x2c,0x02,0x33,0x60,0x51,0xc6,0xf7,0xa4,0x95,
    0xf8,0xc9,0x9a,0xab,0x3c,0x0d,0x5e,0x6f,0x41,0x70,0x23,0x12,0x85,0xb4,0xe7,0xd6,
    0x7a,0x4b,0x18,0x29,0xbe,0x8f,0xdc,0xed,0xc3,0xf2,0xa1,0x90,0x07,0x36,0x65,0x54,
    0x39,0x08,0x5b,0x6a,0xfd,0xcc,0x9f,0xae,0x80,0xb1,0xe2,0xd3,0x44,0x75,0x26,0x17,
    0xfc,0xcd,0x9e,0xaf,0x38,0x09,0x5a,0x6b,0x45,0x74,0x27,0x16,0x81,0xb0,0xe3,0xd2,
    0xbf,0x8e,0xdd,0xec,0x7b,0x4a,0x19,0x28,0x06,0x37,0x64,0x55,0xc2,0xf3,0xa0,0x91,
    0x47,0x76,0x25,0x14,0x83,0xb2,0xe1,0xd0,0xfe,0xcf,0x9c,0xad,0x3a,0x0b,0x58,0x69,
    0x04,0x35,0x66,0x57,0xc0,0xf1,0xa2,0x93,0xbd,0x8c,0xdf,0xee,0x79,0x48,0x1b,0x2a,
    0xc1,0xf0,0xa3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1a,0x2b,0xbc,0x8d,0xde,0xef,
    0x82,0xb3,0xe0,0xd1,0x46,0x77,0x24,0x15,0x3b,0x0a,0x59,0x68,0xff,0xce,0x9d,0xac
};

static const unsigned char aucCRCHi[] = {
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40
};

static const unsigned char aucCRCLo[] = {
    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
    0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
    0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
    0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
    0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
    0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
    0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 
    0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
    0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
    0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
    0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 
    0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
    0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
    0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
    0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
    0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
    0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
    0x41, 0x81, 0x80, 0x40
};

static const unsigned int s_crc32Table[] = {
    0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8,
    0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
    0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6,
    0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84,
    0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
    0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a,
    0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
    0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
    0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
    0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9,
    0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
    0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b,
    0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
    0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c,
    0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
    0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0x0315d626,
    0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
    0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
    0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
    0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a,
    0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
    0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093,
    0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679,
    0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
    0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667,
    0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
    0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};


// Code


// initialize the members of the allocated crc32_data_t struct
void crc32_init(crc32_data_t *crc32Config)
{
    // initialize running crc and byte count
    crc32Config->currentCrc = 0xFFFFFFFF;
    crc32Config->byteCountCrc = 0;
}

// "running" crc32 calculation
void crc32_update(crc32_data_t *crc32Config, const unsigned char *src, unsigned int lengthInBytes)
{
    unsigned int crc = crc32Config->currentCrc;
    crc32Config->byteCountCrc += lengthInBytes;

    while (lengthInBytes--)
    {
        unsigned char c = *src++ & 0xff;
        crc = (crc << 8) ^ s_crc32Table[(crc >> 24) ^ c];
    }

    crc32Config->currentCrc = crc;
}

// finalize the crc32 calculation for non-word-aligned counts
void crc32_finalize(crc32_data_t *crc32Config, unsigned int *hash)
{
    unsigned int crc = crc32Config->currentCrc;
    unsigned int byteCount = crc32Config->byteCountCrc;

    // pad with zeroes
    if (byteCount % 4)
    {
        unsigned int i;
        for (i = byteCount % 4; i < 4; i++)
        {
            crc = (crc << 8) ^ s_crc32Table[(crc >> 24) ^ 0];
        }
    }
    crc32Config->currentCrc = crc;
    *hash = crc32Config->currentCrc;
}

/*****************************************************************************************
* Function Name  : CRC32Software				
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
unsigned int CRC32Software(unsigned char* pData, unsigned int Length)
{

    unsigned int nReg;
    unsigned int nTemp = 0;
    unsigned int i, n;

    nReg = 0xFFFFFFFF;
    for (n = 0; n < Length; n++)
    {
        nReg ^= (unsigned int)pData[n];

        for (i = 0; i < 4; i++)
        {
            nTemp = s_crc32Table[((nReg >> 24) & 0xff)]; 
            nReg <<= 8;
            nReg ^= nTemp;
        }
    }
    return nReg;
} 


/*****************************************************************************************
* Function Name  : CRC16Software				
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
unsigned short CRC16Software(unsigned char *pFrame,unsigned short Length)
{
	unsigned char CRCHi = 0xFF;
	unsigned char CRCLo = 0xFF;
	unsigned int Index = 0;
	unsigned char *pBuf = pFrame;
	while(Length--)
	{
		Index = CRCLo ^ *(pBuf++);
		CRCLo = (unsigned char)(CRCHi^aucCRCHi[Index]);
		CRCHi = aucCRCLo[Index];
	}
	return (unsigned short)(CRCHi<<8|CRCLo);
}

unsigned char CRC8Software(unsigned char *pFrame,unsigned short Length)
{
	unsigned char  crc = 0x00;
	unsigned char *pBuf = pFrame;
    while (Length--)
    {
        crc = CRC8541[crc ^ *pBuf++];
    }
    return (crc);
}

/*****************************************************************************************
* Function Name  : EncryptTEA
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
void EncryptTEA(unsigned int *firstChunk,unsigned int* secondChunk)
{
	int i;
	unsigned int y = *firstChunk;
	unsigned int z = *secondChunk;
	unsigned int sum = 0;

	unsigned int delta = 0x9e3779b9;

	for (i = 0; i < 32; i++)
	{
		sum += delta;
		y += ((z << 4) + TEA_key[0]) ^ (z + sum) ^ ((z >> 5) + TEA_key[1]);
		z += ((y << 4) + TEA_key[2]) ^ (y + sum) ^ ((y >> 5) + TEA_key[3]);
	}

	*firstChunk = y;
	*secondChunk = z;
}

/*****************************************************************************************
* Function Name  : DecryptTEA
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
void DecryptTEA(unsigned int* firstChunk,unsigned int* secondChunk)
{
	int i;
	unsigned int sum = 0;
	unsigned int y = *firstChunk;
	unsigned int z = *secondChunk;
	unsigned int delta = 0x9e3779b9;

	sum = delta << 5;

	for (i = 0; i < 32; i++)
	{
		z -= ((y << 4) + TEA_key[2]) ^ (y + sum) ^ ((y >> 5) + TEA_key[3]);
		y -= ((z << 4) + TEA_key[0]) ^ (z + sum) ^ ((z >> 5) + TEA_key[1]);
		sum -= delta;
	}

	*firstChunk = y;
	*secondChunk = z;
}


/*****************************************************************************************
* Function Name  : EncryptBuffer
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
void EncryptBuffer(unsigned char* buffer, int size)
{
	int i = 0;
	unsigned int FirstData = 0;
	unsigned int SecondData = 0;
	int leftSize = size;

	while ((i < size) && (leftSize >= 8))
	{
		FirstData = (unsigned int)((buffer[i] << 0) | (buffer[i + 1] << 8) | (buffer[i + 2] << 16) | (buffer[i + 3] << 24));
		SecondData = (unsigned int)((buffer[i + 4] << 0) | (buffer[i + 5] << 8) | (buffer[i + 6] << 16) | (buffer[i + 7] << 24));
		EncryptTEA(&FirstData,&SecondData);

		buffer[i] = (FirstData >> 0)&0xFF;
		buffer[i + 1] = (FirstData >> 8)&0xFF;
		buffer[i + 2] = (FirstData >> 16)&0xFF;
		buffer[i + 3] = (FirstData >> 24)&0xFF;

		buffer[i + 4] = (SecondData >> 0)&0xFF;
		buffer[i + 5] = (SecondData >> 8)&0xFF;
		buffer[i + 6] = (SecondData >> 16)&0xFF;
		buffer[i + 7] = (SecondData >> 24)&0xFF;

		i += 8;
		leftSize -= 8;
	}
}

/*****************************************************************************************
* Function Name  : DecryptBuffer
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
void DecryptBuffer(unsigned char* buffer, int size)
{
	int i = 0;
	unsigned int FirstData = 0;
	unsigned int SecondData = 0;
	int leftSize = size;

	while ((i < size) && (leftSize >= 8))
	{
		FirstData = (unsigned int)((buffer[i] << 0) | (buffer[i + 1] << 8) | (buffer[i + 2] << 16) | (buffer[i + 3] << 24));
		SecondData = (unsigned int)((buffer[i + 4] << 0) | (buffer[i + 5] << 8) | (buffer[i + 6] << 16) | (buffer[i + 7] << 24));
		DecryptTEA(&FirstData, &SecondData);

		buffer[i] = (FirstData >> 0)&0xFF;
		buffer[i + 1] = (FirstData >> 8)&0xFF;
		buffer[i + 2] = (FirstData >> 16)&0xFF;
		buffer[i + 3] = (FirstData >> 24)&0xFF;

		buffer[i + 4] = (SecondData >> 0)&0xFF;
		buffer[i + 5] = (SecondData >> 8)&0xFF;
		buffer[i + 6] = (SecondData >> 16)&0xFF;
		buffer[i + 7] = (SecondData >> 24)&0xFF;

		i += 8;
		leftSize -= 8;
	}
}


/*****************************************************************************************
* Function Name  : kalmanFilter_init
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
void kalmanFilter_init(kalman_filter_t *inData,float data,float q,float r)
{
	inData->p = 10;
	inData->q = q;
	inData->r = r;
	inData->kGain = 0;
	inData->prevData = data;
}
//

/*****************************************************************************************
* Function Name  : kalmanFilter_calc
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
float kalmanFilter_calc(kalman_filter_t *inData,float data) 
{
	inData->p = inData->p+inData->q;
	inData->kGain  = inData->p/(inData->p+inData->r);
	
	inData->prevData = inData->prevData + (inData->kGain*(data - inData->prevData));
	inData->p = (1-inData->kGain)*inData->p;
	return inData->prevData;
}
//

/*****************************************************************************************
* Function Name  : average_filter_init
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
int average_filter_init(average_filter_t *pft,int *pbuf_avg,int *pbuf_clc,int avg_length,int avg_lose,int data)
{
    int i;
    pft->p_avg_buf = pbuf_avg;
    pft->p_avg_clc_buf = pbuf_clc;
    
    pft->avg_length = avg_length;
    pft->avg_lose_cnt = avg_lose;
    pft->avg_point = 0;
    
    for(i=0;i<avg_length;i++)
    {
        pbuf_avg[i] = data;
    }
    return 0;
}
//

/*****************************************************************************************
* Function Name  : average_filter_flush
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
int average_filter_flush(average_filter_t *pft,int data)
{
    int i;
    
    for(i=0;i< pft->avg_length;i++)
    {
        pft->p_avg_buf[i] = data;
    }
    return 0;
}
//

/*****************************************************************************************
* Function Name  : average_filter_add
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
int average_filter_add(average_filter_t *p_average,int x)
{
    if(p_average->avg_point >= p_average->avg_length)
    {
        p_average->avg_point = 0;
    }
    p_average->p_avg_buf[p_average->avg_point] = x;
    p_average->avg_point++;
    return 0;
}
//

/*****************************************************************************************
* Function Name  : average_filter_init
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*****************************************************************************************/
int average_filter_calc(average_filter_t *p_average,int* p_vmax,int* p_vmin)
{
    int i,j,temp;
    int length;
    int *pbuf;
    long long utemp;
    
    pbuf = p_average->p_avg_clc_buf;
    length = p_average->avg_length;
    
    for(i = 0;i<length;i++)
    {
       pbuf[i] = p_average->p_avg_buf[i];
    }
    
    for(i=0;i<length;i++)
    {
        for(j=i+1;j<length;j++)
        {
            if(pbuf[i]>pbuf[j])
            {
                temp = pbuf[i];
                pbuf[i] = pbuf[j];
                pbuf[j] = temp;
            }
        }
    }
    
    if(p_vmax != 0)
    {
        *p_vmax = pbuf[length-1];
    }
    
    if(p_vmin != 0)
    {
        *p_vmin = pbuf[0];
    }
    
    utemp = 0;
	for(i=p_average->avg_lose_cnt;i<(length-p_average->avg_lose_cnt);i++)
    {
        utemp = utemp + pbuf[i];
    }
	temp = utemp/(length - p_average->avg_lose_cnt - p_average->avg_lose_cnt);
    return temp;
}


/*******************************************************************************
* Function Name  : findPeaks
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void findPeaks(int *src, int src_lenth, short distance, short *indMax, short *indMax_len, short *indMin, short *indMin_len,short *buf_sign,char *buf_flag_max,char *buf_idelete,char *buf_temp_max)
{
	short *sign = buf_sign;
	int max_index = 0;
	int	min_index = 0;
    
    int max_len;
    int min_len;
    
    short diff;
    
    max_len = 0;
    min_len = 0;
    
	for (int i = 1; i<src_lenth; i++)
	{
		diff = src[i] - src[i - 1];
        
		if (diff>0)
        {            
            sign[i - 1] = 1;
        }
		else if (diff<0)
        {
            sign[i - 1] = -1;
        }
		else
        {            
            sign[i - 1] = 0;
        }
	}
    
	for (int j = 1; j<src_lenth - 1; j++)
	{
		diff = sign[j] - sign[j - 1];
		if (diff<0) 
        {            
            indMax[max_index++] = j;
        }
		else if (diff>0)
        {
            indMin[min_index++] = j;
        }
	}
 
//	int *flag_max_index = (int *)malloc(sizeof(int)*(max_index>min_index ? max_index : min_index));
//	int *idelete = (int *)malloc(sizeof(int)*(max_index>min_index ? max_index : min_index));
//	int *temp_max_index = (int *)malloc(sizeof(int)*(max_index>min_index ? max_index : min_index));
    
	int bigger = 0;
	double tempvalue = 0;
	int i, j, k;
	//
	for (int i = 0; i < max_index; i++)
	{
		buf_flag_max[i] = 0;
		buf_idelete[i] = 0;
	}
	for (i = 0; i < max_index; i++)
	{
		tempvalue = -1;
		for (j = 0; j < max_index; j++)
		{
			if (!buf_flag_max[j])
			{
				if (src[indMax[j]] > tempvalue)
				{
					bigger = j;
					tempvalue = src[indMax[j]];
				}
			}
		}
		buf_flag_max[bigger] = 1;
		if (!buf_idelete[bigger])
		{
			for (k = 0; k < max_index; k++)
			{
				buf_idelete[k] |= ((indMax[k] - distance <= indMax[bigger]) && (indMax[bigger] <= indMax[k] + distance));
			}
			buf_idelete[bigger] = 0;
		}
	}
	for (i = 0, j = 0; i < max_index; i++)
	{
		if (!buf_idelete[i])
			buf_temp_max[j++] = indMax[i];
	}
	for (i = 0; i < max_index; i++)
	{
		if (i < j)
			indMax[i] = buf_temp_max[i];
		else
			indMax[i] = 0;
	}
	max_index = j;
 
	//
	for (int i = 0; i < min_index; i++)
	{
		buf_flag_max[i] = 0;
		buf_idelete[i] = 0;
	}
	for (i = 0; i < min_index; i++)
	{
		tempvalue = 1;
		for (j = 0; j < min_index; j++)
		{
			if (!buf_flag_max[j])
			{
				if (src[indMin[j]] < tempvalue)
				{
					bigger = j;
					tempvalue = src[indMin[j]];
				}
			}
		}
		buf_flag_max[bigger] = 1;
		if (!buf_idelete[bigger])
		{
			for (k = 0; k < min_index; k++)
			{
				buf_idelete[k] |= ((indMin[k] - distance <= indMin[bigger]) && (indMin[bigger] <= indMin[k] + distance));
			}
			buf_idelete[bigger] = 0;
		}
	}
	for (i = 0, j = 0; i < min_index; i++)
	{
		if (!buf_idelete[i])
			buf_temp_max[j++] = indMin[i];
	}
	for (i = 0; i < min_index; i++)
	{
		if (i < j)
			indMin[i] = buf_temp_max[i];
		else
			indMin[i] = 0;
	}
	min_index = j;
 
	*indMax_len = max_index;
	*indMin_len = min_index;
}
//

/*******************************************************************************
* Function Name  : calib_dpoint_init
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void calib_dpoint_init(dpoint_calib_t *dpoint_cal)
{
    dpoint_cal->raw_higher = 100;
    dpoint_cal->real_higher = 100;
    
    dpoint_cal->raw_lower = 0;
    dpoint_cal->real_lower = 0;
	
	dpoint_cal->offset = 0;
    
    dpoint_cal->v_cal_k = 1;
    dpoint_cal->v_cal_b = 0;
}
//


/*******************************************************************************
* Function Name  : calib_dpoint_cal
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int calib_dpoint_cal(dpoint_calib_t *dpoint_cal)
{
	float x1,y1,x2,y2;
	float k1,b1;
	//unsigned short i;
	
	x1 = dpoint_cal->raw_lower;
	y1 = dpoint_cal->real_lower;
	
	x2 = dpoint_cal->raw_higher;
	y2 = dpoint_cal->real_higher;
	
	if((x2<=x1))
	{
		return -1;
	}
	
	k1 = (y2-y1)/(x2-x1);
	b1 = y1 - x1*k1;

	dpoint_cal->v_cal_k = k1;
	dpoint_cal->v_cal_b = b1;
	
	return 0;			
}
//

/*******************************************************************************
* Function Name  : dpoint_cal
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int dpoint_cal(dpoint_calib_t *dpoint,int raw)
{
	float x1,y1;
	
	if(dpoint == 0)
	{
		return 0;
	}
	
	x1 = raw;
	
	y1 = dpoint->v_cal_k * x1 + dpoint->v_cal_b + dpoint->offset;
	
	return (int)y1;
}
//


/*******************************************************************************
* Function Name  : calib_mdpoint_cal
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int calib_mdpoint_cal(mdpoint_calib_t *mdpoint_cal)
{
    int points;
	float x1,y1,x2,y2;
	float k1,b1;
	unsigned short i;
    
    if((mdpoint_cal->calib_point<2)||(mdpoint_cal->calib_point > MULTI_DPOINT_COUNT))
    {
       return -1; 
    }
    
    points = mdpoint_cal->calib_point - 1;
	
    for(i=0;i<points;i++)
    {
        x1 = mdpoint_cal->p_x[i];
        y1 = mdpoint_cal->p_y[i];
        
        x2 = mdpoint_cal->p_x[i+1];
        y2 = mdpoint_cal->p_y[i+1];
        
        k1 = (y2-y1)/(x2-x1);
        b1 = y1 - x1*k1;
        
        mdpoint_cal->v_cal_k[i] = k1;
        mdpoint_cal->v_cal_b[i] = b1;
    }
	
	return 0;			
}
//

/*******************************************************************************
* Function Name  : mdpoint_cal
* Description    : 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int mdpoint_cal(mdpoint_calib_t *mdpoint,int raw)
{
    int points;
    int i;
	float x1,y1;
    
    if((mdpoint->calib_point<2)||(mdpoint->calib_point > MULTI_DPOINT_COUNT))
    {
       return -1; 
    }
    
    points = mdpoint->calib_point;
    
    for(i=0;i<points-1;i++)
    {
        if(mdpoint->p_x[i] > raw)
        {
            break;
        }
    }
    
    if(i > 0)
    {
        i = i-1;
    }
    
    x1 = raw;
    y1 = mdpoint->v_cal_k[i] * x1 + mdpoint->v_cal_b[i] + mdpoint->offset;
	
	return (int)y1;
}
//


//const unsigned int atan2buf[] = { 
//0x00000000,0x00000065,0x000000C9,0x0000012E,0x00000192,0x000001F7,0x0000025B,0x000002C0, 
//0x00000324,0x00000389,0x000003ED,0x00000452,0x000004B7,0x0000051B,0x00000580,0x000005E4, 
//0x00000649,0x000006AD,0x00000712,0x00000777,0x000007DB,0x00000840,0x000008A5,0x00000909, 
//0x0000096E,0x000009D3,0x00000A37,0x00000A9C,0x00000B01,0x00000B65,0x00000BCA,0x00000C2F, 
//0x00000C94,0x00000CF8,0x00000D5D,0x00000DC2,0x00000E27,0x00000E8C,0x00000EF1,0x00000F55, 
//0x00000FBA,0x0000101F,0x00001084,0x000010E9,0x0000114E,0x000011B3,0x00001218,0x0000127D, 
//0x000012E2,0x00001347,0x000013AC,0x00001412,0x00001477,0x000014DC,0x00001541,0x000015A6, 
//0x0000160C,0x00001671,0x000016D6,0x0000173C,0x000017A1,0x00001806,0x0000186C,0x000018D1, 
//0x00001937,0x0000199C,0x00001A02,0x00001A67,0x00001ACD,0x00001B33,0x00001B98,0x00001BFE, 
//0x00001C64,0x00001CCA,0x00001D2F,0x00001D95,0x00001DFB,0x00001E61,0x00001EC7,0x00001F2D, 
//0x00001F93,0x00001FF9,0x0000205F,0x000020C5,0x0000212C,0x00002192,0x000021F8,0x0000225E, 
//0x000022C5,0x0000232B,0x00002392,0x000023F8,0x0000245F,0x000024C5,0x0000252C,0x00002593, 
//0x000025F9,0x00002660,0x000026C7,0x0000272E,0x00002795,0x000027FC,0x00002863,0x000028CA, 
//0x00002931,0x00002998,0x000029FF,0x00002A66,0x00002ACE,0x00002B35,0x00002B9D,0x00002C04, 
//0x00002C6C,0x00002CD3,0x00002D3B,0x00002DA2,0x00002E0A,0x00002E72,0x00002EDA,0x00002F42, 
//0x00002FAA,0x00003012,0x0000307A,0x000030E2,0x0000314A,0x000031B3,0x0000321B,0x00003283, 
//0x000032EC,0x00003354,0x000033BD,0x00003426,0x0000348E,0x000034F7,0x00003560,0x000035C9, 
//0x00003632,0x0000369B,0x00003704,0x0000376D,0x000037D7,0x00003840,0x000038AA,0x00003913, 
//0x0000397D,0x000039E6,0x00003A50,0x00003ABA,0x00003B24,0x00003B8E,0x00003BF8,0x00003C62, 
//0x00003CCC,0x00003D36,0x00003DA0,0x00003E0B,0x00003E75,0x00003EE0,0x00003F4A,0x00003FB5, 
//0x00004020,0x0000408B,0x000040F6,0x00004161,0x000041CC,0x00004237,0x000042A2,0x0000430E, 
//0x00004379,0x000043E5,0x00004451,0x000044BC,0x00004528,0x00004594,0x00004600,0x0000466C, 
//0x000046D8,0x00004745,0x000047B1,0x0000481D,0x0000488A,0x000048F7,0x00004963,0x000049D0, 
//0x00004A3D,0x00004AAA,0x00004B17,0x00004B84,0x00004BF2,0x00004C5F,0x00004CCD,0x00004D3A, 
//0x00004DA8,0x00004E16,0x00004E84,0x00004EF2,0x00004F60,0x00004FCE,0x0000503D,0x000050AB, 
//0x0000511A,0x00005188,0x000051F7,0x00005266,0x000052D5,0x00005344,0x000053B3,0x00005423, 
//0x00005492,0x00005502,0x00005571,0x000055E1,0x00005651,0x000056C1,0x00005731,0x000057A1, 
//0x00005812,0x00005882,0x000058F3,0x00005964,0x000059D5,0x00005A46,0x00005AB7,0x00005B28, 
//0x00005B99,0x00005C0B,0x00005C7C,0x00005CEE,0x00005D60,0x00005DD2,0x00005E44,0x00005EB6, 
//0x00005F28,0x00005F9B,0x0000600E,0x00006080,0x000060F3,0x00006166,0x000061D9,0x0000624D, 
//0x000062C0,0x00006334,0x000063A7,0x0000641B,0x0000648F,0x00006503,0x00006577,0x000065EC, 
//0x00006660,0x000066D5,0x0000674A,0x000067BF,0x00006834,0x000068A9,0x0000691F,0x00006994, 
//0x00006A0A,0x00006A80,0x00006AF6,0x00006B6C,0x00006BE2,0x00006C59,0x00006CCF,0x00006D46, 
//0x00006DBD,0x00006E34,0x00006EAB,0x00006F23,0x00006F9A,0x00007012,0x0000708A,0x00007102, 
//0x0000717A,0x000071F2,0x0000726B,0x000072E4,0x0000735D,0x000073D6,0x0000744F,0x000074C8, 
//0x00007542,0x000075BB,0x00007635,0x000076AF,0x0000772A,0x000077A4,0x0000781F,0x00007899, 
//0x00007914,0x0000798F,0x00007A0B,0x00007A86,0x00007B02,0x00007B7E,0x00007BFA,0x00007C76, 
//0x00007CF2,0x00007D6F,0x00007DEC,0x00007E68,0x00007EE6,0x00007F63,0x00007FE0,0x0000805E, 
//0x000080DC,0x0000815A,0x000081D8,0x00008257,0x000082D6,0x00008355,0x000083D4,0x00008453, 
//0x000084D2,0x00008552,0x000085D2,0x00008652,0x000086D2,0x00008753,0x000087D4,0x00008855, 
//0x000088D6,0x00008957,0x000089D9,0x00008A5A,0x00008ADC,0x00008B5F,0x00008BE1,0x00008C64, 
//0x00008CE7,0x00008D6A,0x00008DED,0x00008E71,0x00008EF4,0x00008F78,0x00008FFD,0x00009081, 
//0x00009106,0x0000918B,0x00009210,0x00009295,0x0000931B,0x000093A1,0x00009427,0x000094AD, 
//0x00009534,0x000095BA,0x00009641,0x000096C9,0x00009750,0x000097D8,0x00009860,0x000098E8, 
//0x00009971,0x000099FA,0x00009A83,0x00009B0C,0x00009B95,0x00009C1F,0x00009CA9,0x00009D34, 
//0x00009DBE,0x00009E49,0x00009ED4,0x00009F5F,0x00009FEB,0x0000A077,0x0000A103,0x0000A190, 
//0x0000A21C,0x0000A2A9,0x0000A336,0x0000A3C4,0x0000A452,0x0000A4E0,0x0000A56E,0x0000A5FD, 
//0x0000A68C,0x0000A71B,0x0000A7AB,0x0000A83A,0x0000A8CA,0x0000A95B,0x0000A9EC,0x0000AA7C, 
//0x0000AB0E,0x0000AB9F,0x0000AC31,0x0000ACC3,0x0000AD56,0x0000ADE9,0x0000AE7C,0x0000AF0F, 
//0x0000AFA3,0x0000B037,0x0000B0CB,0x0000B160,0x0000B1F5,0x0000B28A,0x0000B320,0x0000B3B5, 
//0x0000B44C,0x0000B4E2,0x0000B579,0x0000B610,0x0000B6A8,0x0000B740,0x0000B7D8,0x0000B870, 
//0x0000B909,0x0000B9A3,0x0000BA3C,0x0000BAD6,0x0000BB70,0x0000BC0B,0x0000BCA6,0x0000BD41, 
//0x0000BDDD,0x0000BE79,0x0000BF15,0x0000BFB2,0x0000C04F,0x0000C0EC,0x0000C18A,0x0000C228, 
//0x0000C2C7,0x0000C366,0x0000C405,0x0000C4A5,0x0000C545,0x0000C5E5,0x0000C686,0x0000C727, 
//0x0000C7C9,0x0000C86B,0x0000C90D,0x0000C9B0,0x0000CA53,0x0000CAF6,0x0000CB9A,0x0000CC3F, 
//0x0000CCE3,0x0000CD89,0x0000CE2E,0x0000CED4,0x0000CF7A,0x0000D021,0x0000D0C8,0x0000D170, 
//0x0000D218,0x0000D2C0,0x0000D369,0x0000D413,0x0000D4BC,0x0000D567,0x0000D611,0x0000D6BC, 
//0x0000D768,0x0000D814,0x0000D8C0,0x0000D96D,0x0000DA1A,0x0000DAC8,0x0000DB76,0x0000DC25, 
//0x0000DCD4,0x0000DD83,0x0000DE33,0x0000DEE4,0x0000DF95,0x0000E046,0x0000E0F8,0x0000E1AB, 
//0x0000E25E,0x0000E311,0x0000E3C5,0x0000E479,0x0000E52E,0x0000E5E3,0x0000E699,0x0000E750, 
//0x0000E806,0x0000E8BE,0x0000E976,0x0000EA2E,0x0000EAE7,0x0000EBA0,0x0000EC5A,0x0000ED15, 
//0x0000EDD0,0x0000EE8B,0x0000EF47,0x0000F004,0x0000F0C1,0x0000F17F,0x0000F23D,0x0000F2FC, 
//0x0000F3BB,0x0000F47B,0x0000F53C,0x0000F5FD,0x0000F6BF,0x0000F781,0x0000F844,0x0000F907, 
//0x0000F9CB,0x0000FA8F,0x0000FB55,0x0000FC1A,0x0000FCE1,0x0000FDA8,0x0000FE6F,0x0000FF37, 
//0x00010000,0x000100C9,0x00010193,0x0001025E,0x00010329,0x000103F5,0x000104C2,0x0001058F, 
//0x0001065D,0x0001072B,0x000107FA,0x000108CA,0x0001099A,0x00010A6B,0x00010B3D,0x00010C10, 
//0x00010CE3,0x00010DB6,0x00010E8B,0x00010F60,0x00011036,0x0001110C,0x000111E4,0x000112BC, 
//0x00011394,0x0001146E,0x00011548,0x00011623,0x000116FE,0x000117DA,0x000118B8,0x00011995, 
//0x00011A74,0x00011B53,0x00011C33,0x00011D14,0x00011DF6,0x00011ED8,0x00011FBB,0x0001209F, 
//0x00012184,0x00012269,0x00012350,0x00012437,0x0001251F,0x00012607,0x000126F1,0x000127DB, 
//0x000128C6,0x000129B2,0x00012A9F,0x00012B8D,0x00012C7C,0x00012D6B,0x00012E5C,0x00012F4D, 
//0x0001303F,0x00013132,0x00013226,0x0001331A,0x00013410,0x00013507,0x000135FE,0x000136F7, 
//0x000137F0,0x000138EA,0x000139E5,0x00013AE1,0x00013BDF,0x00013CDD,0x00013DDC,0x00013EDC, 
//0x00013FDD,0x000140DF,0x000141E2,0x000142E6,0x000143EB,0x000144F0,0x000145F8,0x00014700, 
//0x00014809,0x00014913,0x00014A1E,0x00014B2A,0x00014C37,0x00014D46,0x00014E55,0x00014F66, 
//0x00015077,0x0001518A,0x0001529E,0x000153B3,0x000154C9,0x000155E0,0x000156F9,0x00015812, 
//0x0001592D,0x00015A49,0x00015B66,0x00015C84,0x00015DA4,0x00015EC4,0x00015FE6,0x00016109, 
//0x0001622E,0x00016353,0x0001647A,0x000165A2,0x000166CC,0x000167F6,0x00016922,0x00016A4F, 
//0x00016B7E,0x00016CAE,0x00016DDF,0x00016F12,0x00017045,0x0001717B,0x000172B1,0x000173E9, 
//0x00017523,0x0001765E,0x0001779A,0x000178D7,0x00017A17,0x00017B57,0x00017C99,0x00017DDD, 
//0x00017F22,0x00018068,0x000181B0,0x000182F9,0x00018444,0x00018591,0x000186DF,0x0001882F, 
//0x00018980,0x00018AD3,0x00018C27,0x00018D7D,0x00018ED5,0x0001902F,0x0001918A,0x000192E6, 
//0x00019445,0x000195A5,0x00019707,0x0001986A,0x000199CF,0x00019B36,0x00019C9F,0x00019E0A, 
//0x00019F76,0x0001A0E4,0x0001A254,0x0001A3C6,0x0001A53A,0x0001A6B0,0x0001A827,0x0001A9A1, 
//0x0001AB1C,0x0001AC9A,0x0001AE19,0x0001AF9A,0x0001B11D,0x0001B2A3,0x0001B42A,0x0001B5B3, 
//0x0001B73F,0x0001B8CC,0x0001BA5C,0x0001BBEE,0x0001BD82,0x0001BF18,0x0001C0B0,0x0001C24B, 
//0x0001C3E7,0x0001C586,0x0001C727,0x0001C8CB,0x0001CA71,0x0001CC19,0x0001CDC3,0x0001CF70, 
//0x0001D11F,0x0001D2D1,0x0001D485,0x0001D63B,0x0001D7F4,0x0001D9B0,0x0001DB6E,0x0001DD2E, 
//0x0001DEF1,0x0001E0B7,0x0001E27F,0x0001E44A,0x0001E618,0x0001E7E8,0x0001E9BB,0x0001EB91, 
//0x0001ED6A,0x0001EF45,0x0001F123,0x0001F304,0x0001F4E8,0x0001F6CF,0x0001F8B9,0x0001FAA6, 
//0x0001FC96,0x0001FE88,0x0002007E,0x00020277,0x00020473,0x00020673,0x00020875,0x00020A7B, 
//0x00020C84,0x00020E90,0x0002109F,0x000212B2,0x000214C9,0x000216E2,0x000218FF,0x00021B20, 
//0x00021D44,0x00021F6C,0x00022197,0x000223C6,0x000225F9,0x0002282F,0x00022A69,0x00022CA7, 
//0x00022EE9,0x0002312F,0x00023378,0x000235C6,0x00023818,0x00023A6D,0x00023CC7,0x00023F25, 
//0x00024187,0x000243ED,0x00024658,0x000248C7,0x00024B3A,0x00024DB2,0x0002502E,0x000252AF, 
//0x00025534,0x000257BE,0x00025A4D,0x00025CE0,0x00025F78,0x00026215,0x000264B7,0x0002675E, 
//0x00026A0A,0x00026CBB,0x00026F71,0x0002722C,0x000274ED,0x000277B3,0x00027A7E,0x00027D4F, 
//0x00028026,0x00028302,0x000285E3,0x000288CB,0x00028BB8,0x00028EAB,0x000291A4,0x000294A3, 
//0x000297A8,0x00029AB3,0x00029DC4,0x0002A0DC,0x0002A3FB,0x0002A71F,0x0002AA4B,0x0002AD7D, 
//0x0002B0B5,0x0002B3F5,0x0002B73B,0x0002BA89,0x0002BDDD,0x0002C139,0x0002C49C,0x0002C807, 
//0x0002CB79,0x0002CEF2,0x0002D274,0x0002D5FD,0x0002D98E,0x0002DD27,0x0002E0C8,0x0002E471, 
//0x0002E823,0x0002EBDD,0x0002EFA0,0x0002F36C,0x0002F740,0x0002FB1D,0x0002FF04,0x000302F3, 
//0x000306EC,0x00030AEF,0x00030EFB,0x00031311,0x00031730,0x00031B5A,0x00031F8E,0x000323CD, 
//0x00032816,0x00032C69,0x000330C8,0x00033531,0x000339A6,0x00033E26,0x000342B1,0x00034748, 
//0x00034BEB,0x0003509A,0x00035556,0x00035A1D,0x00035EF2,0x000363D3,0x000368C2,0x00036DBD, 
//0x000372C6,0x000377DD,0x00037D02,0x00038235,0x00038776,0x00038CC6,0x00039225,0x00039793, 
//0x00039D11,0x0003A29E,0x0003A83B,0x0003ADE8,0x0003B3A6,0x0003B974,0x0003BF54,0x0003C545, 
//0x0003CB48,0x0003D15C,0x0003D784,0x0003DDBD,0x0003E40A,0x0003EA6A,0x0003F0DE,0x0003F766, 
//0x0003FE02,0x000404B4,0x00040B7A,0x00041256,0x00041949,0x00042051,0x00042771,0x00042EA8, 
//0x000435F7,0x00043D5E,0x000444DE,0x00044C78,0x0004542B,0x00045BF9,0x000463E1,0x00046BE5, 
//0x00047405,0x00047C42,0x0004849B,0x00048D13,0x000495A9,0x00049E5E,0x0004A733,0x0004B029, 
//0x0004B940,0x0004C279,0x0004CBD4,0x0004D553,0x0004DEF6,0x0004E8BF,0x0004F2AD,0x0004FCC3, 
//0x00050700,0x00051166,0x00051BF5,0x000526B0,0x00053196,0x00053CA8,0x000547E9,0x00055359, 
//0x00055EF9,0x00056ACB,0x000576CF,0x00058307,0x00058F75,0x00059C19,0x0005A8F6,0x0005B60C, 
//0x0005C35D,0x0005D0EC,0x0005DEB8,0x0005ECC5,0x0005FB14,0x000609A7,0x0006187F,0x0006279F, 
//0x00063709,0x000646BF,0x000656C4,0x00066718,0x000677C0,0x000688BD,0x00069A12,0x0006ABC2, 
//0x0006BDD0,0x0006D03E,0x0006E310,0x0006F649,0x000709EC,0x00071DFC,0x0007327E,0x00074776, 
//0x00075CE6,0x000772D4,0x00078944,0x0007A03A,0x0007B7BB,0x0007CFCD,0x0007E873,0x000801B5, 
//0x00081B98,0x00083621,0x00085158,0x00086D43,0x000889E9,0x0008A752,0x0008C586,0x0008E48C, 
//0x0009046E,0x00092535,0x000946EB,0x0009699A,0x00098D4D,0x0009B20F,0x0009D7EE,0x0009FEF7, 
//0x000A2736,0x000A50BC,0x000A7B97,0x000AA7D9,0x000AD593,0x000B04DA,0x000B35C0,0x000B685C, 
//0x000B9CC6,0x000BD317,0x000C0B69,0x000C45DA,0x000C828A,0x000CC199,0x000D032C,0x000D476C, 
//0x000D8E82,0x000DD89D,0x000E25EF,0x000E76B0,0x000ECB1B,0x000F2371,0x000F7FFA,0x000FE106, 
//0x001046EA,0x0010B206,0x001122C3,0x00119997,0x00121703,0x00129B97,0x001327F6,0x0013BCD5, 
//0x00145B00,0x0015035D,0x0015B6F1,0x001676E5,0x0017448D,0x0018216E,0x00190F4A,0x001A102B, 
//0x001B2672,0x001C54E8,0x001D9EDA,0x001F0835,0x002095AF,0x00224CFD,0x00243517,0x0026569A, 
//0x0028BC49,0x002B73C6,0x002E8E9A,0x003223B0,0x0036519A,0x003B4205,0x00412F4C,0x00486DB7, 
//0x00517BB6,0x005D1FF3,0x006CA58F,0x0082608E,0x00A2F8FD,0x00D94C4B,0x0145F2C4,0x028BE5EC, 
//}; 


const unsigned int atan2_ltu[] = {
    0,
  228,    
  457,    
  686,    
  915,    
 1143,    
 1372,    
 1601,    
 1830,    
 2059,    
 2288,    
 2517,    
 2746,    
 2975,    
 3205,    
 3434,    
 3664,    
 3893,    
 4123,    
 4352,    
 4582,    
 4812,    
 5042,    
 5272,    
 5503,    
 5733,    
 5964,    
 6194,    
 6425,    
 6656,    
 6888,    
 7119,    
 7351,    
 7582,    
 7814,    
 8046,    
 8279,    
 8511,    
 8744,    
 8977,    
 9210,    
 9443,    
 9677,    
 9911,    
10145,    
10379,    
10614,    
10849,    
11084,    
11320,    
11555,    
11791,    
12028,    
12264,    
12501,    
12738,    
12976,    
13214,    
13452,    
13691,    
13930,    
14169,    
14409,    
14649,    
14889,    
15130,    
15371,    
15612,    
15854,    
16097,    
16339,    
16583,    
16826,    
17070,    
17315,    
17560,    
17805,    
18051,    
18297,    
18544,    
18792,    
19039,    
19288,    
19537,    
19786,    
20036,    
20286,    
20537,    
20789,    
21041,    
21293,    
21547,    
21800,    
22055,    
22310,    
22565,    
22822,    
23078,    
23336,    
23594,    
23853,    
24112,  
24372,
24633,
24894,
25156,
25419,
25683,
25947,
26212,
26478,
26744,
27011,
27280,
27548,
27818,
28088,
28359,
28631,
28904,
29178,
29453,
29728,
30004,
30281,
30559,
30838,
31118,
31399,
31681,
31964,
32247,
32532,
32817,
33104,
33392,
33680,
33970,
34261,
34553,
34846,
35140,
35435,
35731,
36028,
36327,
36626,
36927,
37229,
37532,
37837,
38142,
38449,
38757,    
39067,    
39378,    
39690,    
40003,    
40318,    
40634,    
40951,    
41270,    
41590,    
41912,    
42235,    
42559,    
42885,    
43213,    
43542,    
43872,    
44204,    
44538,    
44873,    
45210,    
45548,    
45888,    
46230,    
46574,    
46919,    
47266,    
47614,    
47965,    
48317,    
48671,    
49027,    
49384,    
49744,    
50106,    
50469,    
50834,    
51202,    
51571,    
51943,    
52316,    
52692,    
53070,    
53449,    
53831,    
54216,    
54602,    
54991,    
55382,    
55775,    
56171,    
56569,    
56969,    
57372,    
57777,    
58185,    
58595,    
59008,    
59424,    
59842,    
60263,    
60687,    
61113,    
61542,    
61974,    
62409,    
62846,    
63287,    
63730,    
64177,    
64627,    
65080,    
    
    

};


const unsigned int atan2_tab[] = { 
    0,   11,   22,   34,   45,   57,   68,   80,   91,  102,  114,  125,  137,  148,  160,  171,  183,  194,  205,  217,
  228,  240,  251,  263,  274,  285,  297,  308,  320,  331,  343,  354,  366,  377,  388,  400,  411,  423,  434,  446,
  457,  468,  480,  491,  503,  514,  526,  537,  549,  560,  571,  583,  594,  606,  617,  629,  640,  651,  663,  674,
  686,  697,  709,  720,  732,  743,  754,  766,  777,  789,  800,  812,  823,  835,  846,  857,  869,  880,  892,  903,
  915,  926,  937,  949,  960,  972,  983,  995, 1006, 1018, 1029, 1040, 1052, 1063, 1075, 1086, 1098, 1109, 1121, 1132,
 1143, 1155, 1166, 1178, 1189, 1201, 1212, 1224, 1235, 1246, 1258, 1269, 1281, 1292, 1304, 1315, 1327, 1338, 1349, 1361,
 1372, 1384, 1395, 1407, 1418, 1430, 1441, 1452, 1464, 1475, 1487, 1498, 1510, 1521, 1532, 1544, 1555, 1567, 1578, 1590,
 1601, 1613, 1624, 1636, 1647, 1658, 1670, 1681, 1693, 1704, 1716, 1727, 1739, 1750, 1761, 1773, 1784, 1796, 1807, 1819,
 1830, 1842, 1853, 1864, 1876, 1887, 1899, 1910, 1922, 1933, 1945, 1956, 1967, 1979, 1990, 2002, 2013, 2025, 2036, 2048,
 2059, 2071, 2082, 2093, 2105, 2116, 2128, 2139, 2151, 2162, 2174, 2185, 2196, 2208, 2219, 2231, 2242, 2254, 2265, 2277,
 2288, 2300, 2311, 2322, 2334, 2345, 2357, 2368, 2380, 2391, 2403, 2414, 2426, 2437, 2448, 2460, 2471, 2483, 2494, 2506,
 2517, 2529, 2540, 2552, 2563, 2574, 2586, 2597, 2609, 2620, 2632, 2643, 2655, 2666, 2678, 2689, 2700, 2712, 2723, 2735,
 2746, 2758, 2769, 2781, 2792, 2804, 2815, 2826, 2838, 2849, 2861, 2872, 2884, 2895, 2907, 2918, 2930, 2941, 2953, 2964,
 2975, 2987, 2998, 3010, 3021, 3033, 3044, 3056, 3067, 3079, 3090, 3102, 3113, 3124, 3136, 3147, 3159, 3170, 3182, 3193,
 3205, 3216, 3228, 3239, 3251, 3262, 3274, 3285, 3296, 3308, 3319, 3331, 3342, 3354, 3365, 3377, 3388, 3400, 3411, 3423,
 3434, 3446, 3457, 3469, 3480, 3491, 3503, 3514, 3526, 3537, 3549, 3560, 3572, 3583, 3595, 3606, 3618, 3629, 3641, 3652,
 3664, 3675, 3686, 3698, 3709, 3721, 3732, 3744, 3755, 3767, 3778, 3790, 3801, 3813, 3824, 3836, 3847, 3859, 3870, 3882,
 3893, 3905, 3916, 3927, 3939, 3950, 3962, 3973, 3985, 3996, 4008, 4019, 4031, 4042, 4054, 4065, 4077, 4088, 4100, 4111,
 4123, 4134, 4146, 4157, 4169, 4180, 4192, 4203, 4215, 4226, 4238, 4249, 4260, 4272, 4283, 4295, 4306, 4318, 4329, 4341,
 4352, 4364, 4375, 4387, 4398, 4410, 4421, 4433, 4444, 4456, 4467, 4479, 4490, 4502, 4513, 4525, 4536, 4548, 4559, 4571,
 4582, 4594, 4605, 4617, 4628, 4640, 4651, 4663, 4674, 4686, 4697, 4709, 4720, 4732, 4743, 4755, 4766, 4778, 4789, 4801,
 4812, 4824, 4835, 4847, 4858, 4870, 4881, 4893, 4904, 4916, 4927, 4939, 4950, 4962, 4973, 4985, 4996, 5008, 5019, 5031,
 5042, 5054, 5065, 5077, 5088, 5100, 5111, 5123, 5134, 5146, 5157, 5169, 5180, 5192, 5203, 5215, 5226, 5238, 5249, 5261,
 5272, 5284, 5295, 5307, 5318, 5330, 5341, 5353, 5365, 5376, 5388, 5399, 5411, 5422, 5434, 5445, 5457, 5468, 5480, 5491,
 5503, 5514, 5526, 5537, 5549, 5560, 5572, 5583, 5595, 5606, 5618, 5629, 5641, 5652, 5664, 5676, 5687, 5699, 5710, 5722,
 5733, 5745, 5756, 5768, 5779, 5791, 5802, 5814, 5825, 5837, 5848, 5860, 5871, 5883, 5895, 5906, 5918, 5929, 5941, 5952,
 5964, 5975, 5987, 5998, 6010, 6021, 6033, 6044, 6056, 6068, 6079, 6091, 6102, 6114, 6125, 6137, 6148, 6160, 6171, 6183,
 6194, 6206, 6218, 6229, 6241, 6252, 6264, 6275, 6287, 6298, 6310, 6321, 6333, 6345, 6356, 6368, 6379, 6391, 6402, 6414,
 6425, 6437, 6448, 6460, 6472, 6483, 6495, 6506, 6518, 6529, 6541, 6552, 6564, 6576, 6587, 6599, 6610, 6622, 6633, 6645,
 6656, 6668, 6680, 6691, 6703, 6714, 6726, 6737, 6749, 6760, 6772, 6784, 6795, 6807, 6818, 6830, 6841, 6853, 6864, 6876,
 6888, 6899, 6911, 6922, 6934, 6945, 6957, 6969, 6980, 6992, 7003, 7015, 7026, 7038, 7050, 7061, 7073, 7084, 7096, 7107,
 7119, 7131, 7142, 7154, 7165, 7177, 7188, 7200, 7212, 7223, 7235, 7246, 7258, 7269, 7281, 7293, 7304, 7316, 7327, 7339,
 7351, 7362, 7374, 7385, 7397, 7408, 7420, 7432, 7443, 7455, 7466, 7478, 7490, 7501, 7513, 7524, 7536, 7548, 7559, 7571,
 7582, 7594, 7605, 7617, 7629, 7640, 7652, 7663, 7675, 7687, 7698, 7710, 7721, 7733, 7745, 7756, 7768, 7779, 7791, 7803,
 7814, 7826, 7837, 7849, 7861, 7872, 7884, 7895, 7907, 7919, 7930, 7942, 7953, 7965, 7977, 7988, 8000, 8011, 8023, 8035,
 8046, 8058, 8070, 8081, 8093, 8104, 8116, 8128, 8139, 8151, 8162, 8174, 8186, 8197, 8209, 8221, 8232, 8244, 8255, 8267,
 8279, 8290, 8302, 8313, 8325, 8337, 8348, 8360, 8372, 8383, 8395, 8406, 8418, 8430, 8441, 8453, 8465, 8476, 8488, 8500,
 8511, 8523, 8534, 8546, 8558, 8569, 8581, 8593, 8604, 8616, 8627, 8639, 8651, 8662, 8674, 8686, 8697, 8709, 8721, 8732,
 8744, 8756, 8767, 8779, 8790, 8802, 8814, 8825, 8837, 8849, 8860, 8872, 8884, 8895, 8907, 8919, 8930, 8942, 8954, 8965,
 8977, 8988, 9000, 9012, 9023, 9035, 9047, 9058, 9070, 9082, 9093, 9105, 9117, 9128, 9140, 9152, 9163, 9175, 9187, 9198,
 9210, 9222, 9233, 9245, 9257, 9268, 9280, 9292, 9303, 9315, 9327, 9338, 9350, 9362, 9373, 9385, 9397, 9408, 9420, 9432,
 9443, 9455, 9467, 9478, 9490, 9502, 9513, 9525, 9537, 9548, 9560, 9572, 9584, 9595, 9607, 9619, 9630, 9642, 9654, 9665,
 9677, 9689, 9700, 9712, 9724, 9735, 9747, 9759, 9771, 9782, 9794, 9806, 9817, 9829, 9841, 9852, 9864, 9876, 9887, 9899,
 9911, 9923, 9934, 9946, 9958, 9969, 9981, 9993,10005,10016,10028,10040,10051,10063,10075,10086,10098,10110,10122,10133,
10145,10157,10168,10180,10192,10204,10215,10227,10239,10250,10262,10274,10286,10297,10309,10321,10332,10344,10356,10368,
10379,10391,10403,10415,10426,10438,10450,10461,10473,10485,10497,10508,10520,10532,10544,10555,10567,10579,10591,10602,
10614,10626,10637,10649,10661,10673,10684,10696,10708,10720,10731,10743,10755,10767,10778,10790,10802,10814,10825,10837,
10849,10861,10872,10884,10896,10908,10919,10931,10943,10955,10966,10978,10990,11002,11014,11025,11037,11049,11061,11072,
11084,11096,11108,11119,11131,11143,11155,11166,11178,11190,11202,11214,11225,11237,11249,11261,11272,11284,11296,11308,
11320,11331,11343,11355,11367,11378,11390,11402,11414,11426,11437,11449,11461,11473,11485,11496,11508,11520,11532,11543,
11555,11567,11579,11591,11602,11614,11626,11638,11650,11661,11673,11685,11697,11709,11720,11732,11744,11756,11768,11779,
11791,11803,11815,11827,11839,11850,11862,11874,11886,11898,11909,11921,11933,11945,11957,11968,11980,11992,12004,12016,
12028,12039,12051,12063,12075,12087,12099,12110,12122,12134,12146,12158,12170,12181,12193,12205,12217,12229,12241,12252,
12264,12276,12288,12300,12312,12323,12335,12347,12359,12371,12383,12395,12406,12418,12430,12442,12454,12466,12477,12489,
12501,12513,12525,12537,12549,12560,12572,12584,12596,12608,12620,12632,12643,12655,12667,12679,12691,12703,12715,12727,
12738,12750,12762,12774,12786,12798,12810,12822,12833,12845,12857,12869,12881,12893,12905,12917,12928,12940,12952,12964,
12976,12988,13000,13012,13024,13035,13047,13059,13071,13083,13095,13107,13119,13131,13142,13154,13166,13178,13190,13202,
13214,13226,13238,13250,13261,13273,13285,13297,13309,13321,13333,13345,13357,13369,13381,13393,13404,13416,13428,13440,
13452,13464,13476,13488,13500,13512,13524,13536,13547,13559,13571,13583,13595,13607,13619,13631,13643,13655,13667,13679,
13691,13703,13715,13726,13738,13750,13762,13774,13786,13798,13810,13822,13834,13846,13858,13870,13882,13894,13906,13918,
13930,13942,13954,13965,13977,13989,14001,14013,14025,14037,14049,14061,14073,14085,14097,14109,14121,14133,14145,14157,
14169,14181,14193,14205,14217,14229,14241,14253,14265,14277,14289,14301,14313,14325,14337,14349,14361,14373,14385,14397,
14409,14421,14433,14445,14456,14468,14480,14492,14504,14516,14528,14540,14552,14564,14576,14588,14601,14613,14625,14637,
14649,14661,14673,14685,14697,14709,14721,14733,14745,14757,14769,14781,14793,14805,14817,14829,14841,14853,14865,14877,
14889,14901,14913,14925,14937,14949,14961,14973,14985,14997,15009,15021,15033,15045,15057,15069,15081,15094,15106,15118,
15130,15142,15154,15166,15178,15190,15202,15214,15226,15238,15250,15262,15274,15286,15298,15311,15323,15335,15347,15359,
15371,15383,15395,15407,15419,15431,15443,15455,15467,15479,15492,15504,15516,15528,15540,15552,15564,15576,15588,15600,
15612,15624,15637,15649,15661,15673,15685,15697,15709,15721,15733,15745,15757,15770,15782,15794,15806,15818,15830,15842,
15854,15866,15879,15891,15903,15915,15927,15939,15951,15963,15975,15988,16000,16012,16024,16036,16048,16060,16072,16085,
16097,16109,16121,16133,16145,16157,16169,16182,16194,16206,16218,16230,16242,16254,16267,16279,16291,16303,16315,16327,
16339,16352,16364,16376,16388,16400,16412,16425,16437,16449,16461,16473,16485,16497,16510,16522,16534,16546,16558,16570,
16583,16595,16607,16619,16631,16644,16656,16668,16680,16692,16704,16717,16729,16741,16753,16765,16778,16790,16802,16814,
16826,16838,16851,16863,16875,16887,16899,16912,16924,16936,16948,16960,16973,16985,16997,17009,17022,17034,17046,17058,
17070,17083,17095,17107,17119,17131,17144,17156,17168,17180,17193,17205,17217,17229,17241,17254,17266,17278,17290,17303,
17315,17327,17339,17352,17364,17376,17388,17401,17413,17425,17437,17450,17462,17474,17486,17499,17511,17523,17535,17548,
17560,17572,17584,17597,17609,17621,17633,17646,17658,17670,17682,17695,17707,17719,17732,17744,17756,17768,17781,17793,
17805,17818,17830,17842,17854,17867,17879,17891,17904,17916,17928,17940,17953,17965,17977,17990,18002,18014,18027,18039,
18051,18063,18076,18088,18100,18113,18125,18137,18150,18162,18174,18187,18199,18211,18224,18236,18248,18260,18273,18285,
18297,18310,18322,18334,18347,18359,18371,18384,18396,18408,18421,18433,18446,18458,18470,18483,18495,18507,18520,18532,
18544,18557,18569,18581,18594,18606,18618,18631,18643,18656,18668,18680,18693,18705,18717,18730,18742,18755,18767,18779,
18792,18804,18816,18829,18841,18854,18866,18878,18891,18903,18915,18928,18940,18953,18965,18977,18990,19002,19015,19027,
19039,19052,19064,19077,19089,19102,19114,19126,19139,19151,19164,19176,19188,19201,19213,19226,19238,19251,19263,19275,
19288,19300,19313,19325,19338,19350,19362,19375,19387,19400,19412,19425,19437,19449,19462,19474,19487,19499,19512,19524,
19537,19549,19562,19574,19586,19599,19611,19624,19636,19649,19661,19674,19686,19699,19711,19724,19736,19749,19761,19774,
19786,19798,19811,19823,19836,19848,19861,19873,19886,19898,19911,19923,19936,19948,19961,19973,19986,19998,20011,20023,
20036,20048,20061,20073,20086,20098,20111,20123,20136,20148,20161,20174,20186,20199,20211,20224,20236,20249,20261,20274,
20286,20299,20311,20324,20336,20349,20362,20374,20387,20399,20412,20424,20437,20449,20462,20474,20487,20500,20512,20525,
20537,20550,20562,20575,20587,20600,20613,20625,20638,20650,20663,20675,20688,20701,20713,20726,20738,20751,20764,20776,
20789,20801,20814,20827,20839,20852,20864,20877,20890,20902,20915,20927,20940,20953,20965,20978,20990,21003,21016,21028,
21041,21053,21066,21079,21091,21104,21117,21129,21142,21154,21167,21180,21192,21205,21218,21230,21243,21256,21268,21281,
21293,21306,21319,21331,21344,21357,21369,21382,21395,21407,21420,21433,21445,21458,21471,21483,21496,21509,21521,21534,
21547,21559,21572,21585,21597,21610,21623,21635,21648,21661,21673,21686,21699,21712,21724,21737,21750,21762,21775,21788,
21800,21813,21826,21839,21851,21864,21877,21889,21902,21915,21928,21940,21953,21966,21978,21991,22004,22017,22029,22042,
22055,22068,22080,22093,22106,22118,22131,22144,22157,22169,22182,22195,22208,22220,22233,22246,22259,22271,22284,22297,
22310,22323,22335,22348,22361,22374,22386,22399,22412,22425,22437,22450,22463,22476,22489,22501,22514,22527,22540,22553,
22565,22578,22591,22604,22617,22629,22642,22655,22668,22681,22693,22706,22719,22732,22745,22757,22770,22783,22796,22809,
22822,22834,22847,22860,22873,22886,22899,22911,22924,22937,22950,22963,22976,22988,23001,23014,23027,23040,23053,23066,
23078,23091,23104,23117,23130,23143,23156,23168,23181,23194,23207,23220,23233,23246,23259,23271,23284,23297,23310,23323,
23336,23349,23362,23374,23387,23400,23413,23426,23439,23452,23465,23478,23491,23504,23516,23529,23542,23555,23568,23581,
23594,23607,23620,23633,23646,23659,23671,23684,23697,23710,23723,23736,23749,23762,23775,23788,23801,23814,23827,23840,
23853,23866,23879,23892,23904,23917,23930,23943,23956,23969,23982,23995,24008,24021,24034,24047,24060,24073,24086,24099,
24112,24125,24138,24151,24164,24177,24190,24203,24216,24229,24242,24255,24268,24281,24294,24307,24320,24333,24346,24359,
24372,24385,24398,24411,24424,24437,24450,24463,24476,24489,24502,24515,24528,24542,24555,24568,24581,24594,24607,24620,
24633,24646,24659,24672,24685,24698,24711,24724,24737,24750,24763,24777,24790,24803,24816,24829,24842,24855,24868,24881,
24894,24907,24920,24934,24947,24960,24973,24986,24999,25012,25025,25038,25051,25065,25078,25091,25104,25117,25130,25143,
25156,25170,25183,25196,25209,25222,25235,25248,25261,25275,25288,25301,25314,25327,25340,25353,25367,25380,25393,25406,
25419,25432,25446,25459,25472,25485,25498,25511,25525,25538,25551,25564,25577,25590,25604,25617,25630,25643,25656,25670,
25683,25696,25709,25722,25736,25749,25762,25775,25788,25802,25815,25828,25841,25854,25868,25881,25894,25907,25921,25934,
25947,25960,25974,25987,26000,26013,26026,26040,26053,26066,26079,26093,26106,26119,26132,26146,26159,26172,26185,26199,
26212,26225,26239,26252,26265,26278,26292,26305,26318,26332,26345,26358,26371,26385,26398,26411,26425,26438,26451,26464,
26478,26491,26504,26518,26531,26544,26558,26571,26584,26598,26611,26624,26638,26651,26664,26678,26691,26704,26718,26731,
26744,26758,26771,26784,26798,26811,26824,26838,26851,26864,26878,26891,26905,26918,26931,26945,26958,26971,26985,26998,
27011,27025,27038,27052,27065,27078,27092,27105,27119,27132,27145,27159,27172,27186,27199,27212,27226,27239,27253,27266,
27280,27293,27306,27320,27333,27347,27360,27373,27387,27400,27414,27427,27441,27454,27468,27481,27494,27508,27521,27535,
27548,27562,27575,27589,27602,27616,27629,27643,27656,27670,27683,27696,27710,27723,27737,27750,27764,27777,27791,27804,
27818,27831,27845,27858,27872,27885,27899,27912,27926,27939,27953,27966,27980,27994,28007,28021,28034,28048,28061,28075,
28088,28102,28115,28129,28142,28156,28170,28183,28197,28210,28224,28237,28251,28264,28278,28292,28305,28319,28332,28346,
28359,28373,28387,28400,28414,28427,28441,28455,28468,28482,28495,28509,28523,28536,28550,28563,28577,28591,28604,28618,
28631,28645,28659,28672,28686,28700,28713,28727,28741,28754,28768,28781,28795,28809,28822,28836,28850,28863,28877,28891,
28904,28918,28932,28945,28959,28973,28986,29000,29014,29027,29041,29055,29068,29082,29096,29110,29123,29137,29151,29164,
29178,29192,29205,29219,29233,29247,29260,29274,29288,29301,29315,29329,29343,29356,29370,29384,29398,29411,29425,29439,
29453,29466,29480,29494,29508,29521,29535,29549,29563,29576,29590,29604,29618,29631,29645,29659,29673,29687,29700,29714,
29728,29742,29756,29769,29783,29797,29811,29825,29838,29852,29866,29880,29894,29907,29921,29935,29949,29963,29977,29990,
30004,30018,30032,30046,30060,30073,30087,30101,30115,30129,30143,30157,30170,30184,30198,30212,30226,30240,30254,30268,
30281,30295,30309,30323,30337,30351,30365,30379,30392,30406,30420,30434,30448,30462,30476,30490,30504,30518,30532,30546,
30559,30573,30587,30601,30615,30629,30643,30657,30671,30685,30699,30713,30727,30741,30755,30769,30783,30796,30810,30824,
30838,30852,30866,30880,30894,30908,30922,30936,30950,30964,30978,30992,31006,31020,31034,31048,31062,31076,31090,31104,
31118,31132,31146,31160,31174,31188,31202,31216,31230,31245,31259,31273,31287,31301,31315,31329,31343,31357,31371,31385,
31399,31413,31427,31441,31455,31469,31484,31498,31512,31526,31540,31554,31568,31582,31596,31610,31624,31639,31653,31667,
31681,31695,31709,31723,31737,31751,31766,31780,31794,31808,31822,31836,31850,31864,31879,31893,31907,31921,31935,31949,
31964,31978,31992,32006,32020,32034,32049,32063,32077,32091,32105,32119,32134,32148,32162,32176,32190,32205,32219,32233,
32247,32261,32276,32290,32304,32318,32332,32347,32361,32375,32389,32404,32418,32432,32446,32461,32475,32489,32503,32518,
32532,32546,32560,32575,32589,32603,32617,32632,32646,32660,32675,32689,32703,32717,32732,32746,32760,32775,32789,32803,
32817,32832,32846,32860,32875,32889,32903,32918,32932,32946,32961,32975,32989,33004,33018,33032,33047,33061,33075,33090,
33104,33118,33133,33147,33162,33176,33190,33205,33219,33233,33248,33262,33277,33291,33305,33320,33334,33349,33363,33377,
33392,33406,33421,33435,33449,33464,33478,33493,33507,33522,33536,33550,33565,33579,33594,33608,33623,33637,33652,33666,
33680,33695,33709,33724,33738,33753,33767,33782,33796,33811,33825,33840,33854,33869,33883,33898,33912,33927,33941,33956,
33970,33985,33999,34014,34028,34043,34057,34072,34086,34101,34115,34130,34144,34159,34174,34188,34203,34217,34232,34246,
34261,34275,34290,34305,34319,34334,34348,34363,34377,34392,34407,34421,34436,34450,34465,34480,34494,34509,34523,34538,
34553,34567,34582,34597,34611,34626,34640,34655,34670,34684,34699,34714,34728,34743,34758,34772,34787,34802,34816,34831,
34846,34860,34875,34890,34904,34919,34934,34948,34963,34978,34992,35007,35022,35037,35051,35066,35081,35095,35110,35125,
35140,35154,35169,35184,35199,35213,35228,35243,35257,35272,35287,35302,35317,35331,35346,35361,35376,35390,35405,35420,
35435,35449,35464,35479,35494,35509,35523,35538,35553,35568,35583,35597,35612,35627,35642,35657,35672,35686,35701,35716,
35731,35746,35761,35775,35790,35805,35820,35835,35850,35865,35879,35894,35909,35924,35939,35954,35969,35984,35998,36013,
36028,36043,36058,36073,36088,36103,36118,36133,36147,36162,36177,36192,36207,36222,36237,36252,36267,36282,36297,36312,
36327,36342,36357,36372,36387,36401,36416,36431,36446,36461,36476,36491,36506,36521,36536,36551,36566,36581,36596,36611,
36626,36641,36656,36671,36686,36701,36716,36731,36747,36762,36777,36792,36807,36822,36837,36852,36867,36882,36897,36912,
36927,36942,36957,36972,36987,37003,37018,37033,37048,37063,37078,37093,37108,37123,37138,37154,37169,37184,37199,37214,
37229,37244,37259,37275,37290,37305,37320,37335,37350,37365,37381,37396,37411,37426,37441,37456,37472,37487,37502,37517,
37532,37548,37563,37578,37593,37608,37624,37639,37654,37669,37684,37700,37715,37730,37745,37761,37776,37791,37806,37821,
37837,37852,37867,37882,37898,37913,37928,37944,37959,37974,37989,38005,38020,38035,38051,38066,38081,38096,38112,38127,
38142,38158,38173,38188,38204,38219,38234,38250,38265,38280,38296,38311,38326,38342,38357,38372,38388,38403,38418,38434,
38449,38465,38480,38495,38511,38526,38542,38557,38572,38588,38603,38619,38634,38649,38665,38680,38696,38711,38727,38742,
38757,38773,38788,38804,38819,38835,38850,38866,38881,38896,38912,38927,38943,38958,38974,38989,39005,39020,39036,39051,
39067,39082,39098,39113,39129,39144,39160,39175,39191,39206,39222,39238,39253,39269,39284,39300,39315,39331,39346,39362,
39378,39393,39409,39424,39440,39455,39471,39487,39502,39518,39533,39549,39565,39580,39596,39611,39627,39643,39658,39674,
39690,39705,39721,39736,39752,39768,39783,39799,39815,39830,39846,39862,39877,39893,39909,39924,39940,39956,39971,39987,
40003,40019,40034,40050,40066,40081,40097,40113,40129,40144,40160,40176,40191,40207,40223,40239,40254,40270,40286,40302,
40318,40333,40349,40365,40381,40396,40412,40428,40444,40460,40475,40491,40507,40523,40539,40554,40570,40586,40602,40618,
40634,40649,40665,40681,40697,40713,40729,40744,40760,40776,40792,40808,40824,40840,40856,40871,40887,40903,40919,40935,
40951,40967,40983,40999,41015,41031,41046,41062,41078,41094,41110,41126,41142,41158,41174,41190,41206,41222,41238,41254,
41270,41286,41302,41318,41334,41350,41366,41382,41398,41414,41430,41446,41462,41478,41494,41510,41526,41542,41558,41574,
41590,41606,41622,41638,41654,41670,41686,41702,41718,41734,41751,41767,41783,41799,41815,41831,41847,41863,41879,41895,
41912,41928,41944,41960,41976,41992,42008,42024,42041,42057,42073,42089,42105,42121,42138,42154,42170,42186,42202,42218,
42235,42251,42267,42283,42299,42316,42332,42348,42364,42380,42397,42413,42429,42445,42462,42478,42494,42510,42527,42543,
42559,42575,42592,42608,42624,42640,42657,42673,42689,42706,42722,42738,42754,42771,42787,42803,42820,42836,42852,42869,
42885,42901,42918,42934,42950,42967,42983,43000,43016,43032,43049,43065,43081,43098,43114,43131,43147,43163,43180,43196,
43213,43229,43245,43262,43278,43295,43311,43328,43344,43360,43377,43393,43410,43426,43443,43459,43476,43492,43509,43525,
43542,43558,43574,43591,43607,43624,43641,43657,43674,43690,43707,43723,43740,43756,43773,43789,43806,43822,43839,43855,
43872,43889,43905,43922,43938,43955,43971,43988,44005,44021,44038,44054,44071,44088,44104,44121,44138,44154,44171,44187,
44204,44221,44237,44254,44271,44287,44304,44321,44337,44354,44371,44387,44404,44421,44437,44454,44471,44488,44504,44521,
44538,44554,44571,44588,44605,44621,44638,44655,44672,44688,44705,44722,44739,44755,44772,44789,44806,44823,44839,44856,
44873,44890,44907,44923,44940,44957,44974,44991,45007,45024,45041,45058,45075,45092,45109,45125,45142,45159,45176,45193,
45210,45227,45244,45260,45277,45294,45311,45328,45345,45362,45379,45396,45413,45430,45447,45463,45480,45497,45514,45531,
45548,45565,45582,45599,45616,45633,45650,45667,45684,45701,45718,45735,45752,45769,45786,45803,45820,45837,45854,45871,
45888,45905,45922,45939,45957,45974,45991,46008,46025,46042,46059,46076,46093,46110,46127,46144,46162,46179,46196,46213,
46230,46247,46264,46281,46299,46316,46333,46350,46367,46384,46402,46419,46436,46453,46470,46487,46505,46522,46539,46556,
46574,46591,46608,46625,46642,46660,46677,46694,46711,46729,46746,46763,46780,46798,46815,46832,46849,46867,46884,46901,
46919,46936,46953,46971,46988,47005,47023,47040,47057,47075,47092,47109,47127,47144,47161,47179,47196,47213,47231,47248,
47266,47283,47300,47318,47335,47353,47370,47387,47405,47422,47440,47457,47475,47492,47509,47527,47544,47562,47579,47597,
47614,47632,47649,47667,47684,47702,47719,47737,47754,47772,47789,47807,47824,47842,47859,47877,47894,47912,47929,47947,
47965,47982,48000,48017,48035,48052,48070,48088,48105,48123,48140,48158,48176,48193,48211,48229,48246,48264,48282,48299,
48317,48334,48352,48370,48387,48405,48423,48441,48458,48476,48494,48511,48529,48547,48564,48582,48600,48618,48635,48653,
48671,48689,48706,48724,48742,48760,48777,48795,48813,48831,48849,48866,48884,48902,48920,48938,48955,48973,48991,49009,
49027,49045,49062,49080,49098,49116,49134,49152,49170,49187,49205,49223,49241,49259,49277,49295,49313,49331,49349,49366,
49384,49402,49420,49438,49456,49474,49492,49510,49528,49546,49564,49582,49600,49618,49636,49654,49672,49690,49708,49726,
49744,49762,49780,49798,49816,49834,49852,49870,49888,49906,49925,49943,49961,49979,49997,50015,50033,50051,50069,50087,
50106,50124,50142,50160,50178,50196,50214,50233,50251,50269,50287,50305,50323,50342,50360,50378,50396,50414,50433,50451,
50469,50487,50505,50524,50542,50560,50578,50597,50615,50633,50651,50670,50688,50706,50725,50743,50761,50779,50798,50816,
50834,50853,50871,50889,50908,50926,50944,50963,50981,51000,51018,51036,51055,51073,51091,51110,51128,51147,51165,51183,
51202,51220,51239,51257,51276,51294,51312,51331,51349,51368,51386,51405,51423,51442,51460,51479,51497,51516,51534,51553,
51571,51590,51608,51627,51645,51664,51682,51701,51720,51738,51757,51775,51794,51812,51831,51850,51868,51887,51905,51924,
51943,51961,51980,51999,52017,52036,52055,52073,52092,52111,52129,52148,52167,52185,52204,52223,52241,52260,52279,52297,
52316,52335,52354,52372,52391,52410,52429,52447,52466,52485,52504,52523,52541,52560,52579,52598,52617,52635,52654,52673,
52692,52711,52729,52748,52767,52786,52805,52824,52843,52862,52880,52899,52918,52937,52956,52975,52994,53013,53032,53051,
53070,53088,53107,53126,53145,53164,53183,53202,53221,53240,53259,53278,53297,53316,53335,53354,53373,53392,53411,53430,
53449,53468,53487,53507,53526,53545,53564,53583,53602,53621,53640,53659,53678,53697,53717,53736,53755,53774,53793,53812,
53831,53851,53870,53889,53908,53927,53946,53966,53985,54004,54023,54042,54062,54081,54100,54119,54139,54158,54177,54196,
54216,54235,54254,54273,54293,54312,54331,54351,54370,54389,54409,54428,54447,54467,54486,54505,54525,54544,54563,54583,
54602,54621,54641,54660,54680,54699,54718,54738,54757,54777,54796,54816,54835,54854,54874,54893,54913,54932,54952,54971,
54991,55010,55030,55049,55069,55088,55108,55127,55147,55166,55186,55205,55225,55245,55264,55284,55303,55323,55343,55362,
55382,55401,55421,55441,55460,55480,55499,55519,55539,55558,55578,55598,55617,55637,55657,55676,55696,55716,55736,55755,
55775,55795,55814,55834,55854,55874,55893,55913,55933,55953,55973,55992,56012,56032,56052,56072,56091,56111,56131,56151,
56171,56190,56210,56230,56250,56270,56290,56310,56330,56349,56369,56389,56409,56429,56449,56469,56489,56509,56529,56549,
56569,56589,56609,56629,56649,56669,56689,56709,56729,56749,56769,56789,56809,56829,56849,56869,56889,56909,56929,56949,
56969,56989,57009,57029,57049,57070,57090,57110,57130,57150,57170,57190,57210,57231,57251,57271,57291,57311,57332,57352,
57372,57392,57412,57433,57453,57473,57493,57514,57534,57554,57574,57595,57615,57635,57655,57676,57696,57716,57737,57757,
57777,57798,57818,57838,57859,57879,57899,57920,57940,57960,57981,58001,58022,58042,58062,58083,58103,58124,58144,58165,
58185,58206,58226,58246,58267,58287,58308,58328,58349,58369,58390,58410,58431,58452,58472,58493,58513,58534,58554,58575,
58595,58616,58637,58657,58678,58698,58719,58740,58760,58781,58802,58822,58843,58864,58884,58905,58926,58946,58967,58988,
59008,59029,59050,59071,59091,59112,59133,59154,59174,59195,59216,59237,59257,59278,59299,59320,59341,59361,59382,59403,
59424,59445,59466,59486,59507,59528,59549,59570,59591,59612,59633,59654,59675,59695,59716,59737,59758,59779,59800,59821,
59842,59863,59884,59905,59926,59947,59968,59989,60010,60031,60052,60073,60094,60115,60136,60157,60179,60200,60221,60242,
60263,60284,60305,60326,60347,60369,60390,60411,60432,60453,60474,60496,60517,60538,60559,60580,60602,60623,60644,60665,
60687,60708,60729,60750,60772,60793,60814,60835,60857,60878,60899,60921,60942,60963,60985,61006,61027,61049,61070,61091,
61113,61134,61156,61177,61198,61220,61241,61263,61284,61306,61327,61348,61370,61391,61413,61434,61456,61477,61499,61520,
61542,61563,61585,61607,61628,61650,61671,61693,61714,61736,61758,61779,61801,61822,61844,61866,61887,61909,61930,61952,
61974,61995,62017,62039,62061,62082,62104,62126,62147,62169,62191,62213,62234,62256,62278,62300,62321,62343,62365,62387,
62409,62430,62452,62474,62496,62518,62540,62561,62583,62605,62627,62649,62671,62693,62715,62737,62758,62780,62802,62824,
62846,62868,62890,62912,62934,62956,62978,63000,63022,63044,63066,63088,63110,63132,63154,63176,63199,63221,63243,63265,
63287,63309,63331,63353,63375,63397,63420,63442,63464,63486,63508,63530,63553,63575,63597,63619,63642,63664,63686,63708,
63730,63753,63775,63797,63820,63842,63864,63886,63909,63931,63953,63976,63998,64020,64043,64065,64088,64110,64132,64155,
64177,64200,64222,64244,64267,64289,64312,64334,64357,64379,64402,64424,64447,64469,64492,64514,64537,64559,64582,64604,
64627,64649,64672,64694,64717,64740,64762,64785,64808,64830,64853,64875,64898,64921,64943,64966,64989,65011,65034,65057,
65080,65102,65125,65148,65170,65193,65216,65239,65262,65284,65307,65330,65353,65376,65398,65421,65444,65467,65490,65536,

};

// signed short atan2s16(signed short y, signed short x) 
// { 
//    signed short i; 
//    unsigned int z; 
//
//    if(x == 0) 
//    { 
//        if (y == 0) i = 0; 
//        else        i = 1023; 
//    } 
//    else 
//    { 
//        z = ((y < 0) ? (0 - y) : (y)) * 65536u / ((x < 0) ? (0 - x) : (x)); 
//        i = 0; 
//        if (atan2buf[i + 512] <= z) i += 512; 
//        if (atan2buf[i + 256] <= z) i += 256; 
//        if (atan2buf[i + 128] <= z) i += 128; 
//        if (atan2buf[i + 64] <= z) i += 64; 
//        if (atan2buf[i + 32] <= z) i += 32; 
//        if (atan2buf[i + 16] <= z) i += 16; 
//        if (atan2buf[i + 8] <= z) i += 8; 
//        if (atan2buf[i + 4] <= z) i += 4; 
//        if (atan2buf[i + 2] <= z) i += 2; 
//        if (atan2buf[i + 1] <= z) i += 1; 
//    } 
//    i = i * 900 / 1024; 
//
//    if (y < 0) 
//    { 
//        if (x < 0) 
//           i =   i - 1800; 
//        else      
//           i= -i; 
//    } 
//    else 
//    {  
//        if (x < 0)
//          i= -i + 1800; 
//        //else       
//        //   i = i; 
//    } 
//   
//    if(i < 0)
//       i += 3600; 
//   
//    return  i; 
// }

int atan2s32(int y,int x) 
{
    
    int angle;
    int value;
    short sig = 0;
    
    short i;
    short j;
    
    if(y<=0)
    {
        sig = 1;
        y=y*-1;
    }
    
    
    if(x==0)
    {
        if(y==0)
        {
            angle = 0;
        }
        else
        {
            angle = 4500;
        }
    }
    else if(y>x)
    {
        angle = 4500;
    }
    else
    {
        if(x<0)
        {
            x = x*-1;
        }
        
        
        
        
        value = (y*65536)/x;
        for(i=0;i<224;i++)
        {
            if(value < atan2_ltu[i+1])
            {
                break;
            }
        }
        
        for(j=0;j<20;j++)
        {
            if(value < atan2_tab[i*20 + j + 1])
            {
                break;
            }
        }
        
        angle = i*20 + j;
        
        if(sig)
        {
            angle = angle*-1;
        }
    }
    return angle;
}

unsigned int rs_sqrt(unsigned int num)
{
	/*
	 * Implements an integer square root
	 *
	 * From: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
	 */

	unsigned int  res = 0;
	unsigned int  bit = 1 << 30;
	/* The second-to-top bit is set:
	 *	1 << 14 for 16-bits, 1 << 30 for 32 bits
	 */

	 /* "bit" starts at the highest power of four <= the argument. */
	while (bit > num)
		bit >>= 2;


	while (bit != 0) {
		if (num >= res + bit) {
			num -= res + bit;
			res = (res >> 1) + bit;
		} else
			res >>= 1;

		bit >>= 2;
	}

	return res;
}

short high_pass_filter_s16(short input,int *p_prev,unsigned short alpha)
{   
    int output;
    
    output = alpha * (input - *p_prev) + *p_prev;
    *p_prev = output/100;
    
    return *p_prev;
}


short low_pass_filter_s16(short input,int *p_prev,unsigned short alpha)
{   
    int output;
    
    output = alpha*input+(100-alpha)* *p_prev;
    *p_prev = output/100;
    
    return *p_prev;
}


/**********************************(C)COPYRIGHT 2016 Rsestudio ************************/
/*****************************************END OF FILE**********************************/

